<?php
require_once(PATH_DB_BROKER."db.php");
require_once(PATH_DB_MAIN."stock.php");
require_once(PATH_DB_MAIN."utility.php");

define("MULTIPLE_TIMESTAMP_ID_COLUMN_NAME", "step");


class TBL_StockData{
	private $columns;
	private $name;
	private $dbBroker;
	private $hasTickData;
	private $dataTypeName;
	
	static protected $colTypes = null;

	static protected function addQuote(&$item){
		$item = "\"".$item."\"";
	}
	
	static function init(){
		if(isset(TBL_StockData::$colTypes) == false){
			TBL_StockData::$colTypes = array("DT" => "DATETIME", "F" => "FLOAT", "I" => "INTEGER");
		}
	}
	
	public function __construct($tickerName, $dataType, $multipleTimestamp){
		TBL_StockData::init();
		
		$this->dataTypeName = $dataType;
		$classMemberNames = array_keys(get_class_vars($dataType));
		
		foreach($classMemberNames as $i => $memberName){
			list($cType, $cName) = explode("_", $memberName);
			$this->columns[] = array("type" => TBL_StockData::$colTypes[$cType], "name" => $cName);
		}
		
		$this->name = "TBL_".str_replace(".", "_", $tickerName)."_".count($this->columns);
		$this->hasTickData = $multipleTimestamp;

		$this->dbBroker = new dbMySQL(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD);
		if($this->dbBroker->TableExists($this->name) == false){
			if($this->hasTickData){
				$this->dbBroker->TableCreateMultipleKey($this->name, $this->columns, MULTIPLE_TIMESTAMP_ID_COLUMN_NAME);
			}
			else
				$this->dbBroker->TableCreate($this->name, $this->columns);
		}
	}

	public function CheckIfDataExist($ts){			// return BOOL if Exists($ts)
		if($this->dbBroker->GetRecord($this->name, $this->columns[0], $ts))
			return true;

		return false;
	}

	public function SaveData($data){
		$record = $this->Data2Record($data);
		$this->dbBroker->AddRecord($this->name, $record["columns"], $record["values"]);
	}

	public function IsDifferent($ts, $data){		// return (record[$ts] != $data)
		$storedRecord = $this->dbBroker->GetRecord($this->name, $this->columns[0]["name"], $ts);
		foreach($data as $k => $val){
			if($storedRecord[$k] != $val)
				return true;
		}
		return false;
	}
	
	public function HasData($from, $to, $step){		// for($i = $from; $i < $to; $i += $step) CheckIfDataExist($i)
		for($i = $from; $i < $to; $i += $step)
			if(CheckIfDataExist($i) == false)
				return false;
		return true;
	}

	public function GetData($from, $to, $step){		// for($i = $from; $i < $to; $i += $step) $result = {$result, $db->read($i)}
		$result = array();
		for($i = $from; $i < $to; $i += $step){
			$nRecord = $this->dbBroker->GetRecord($this->name, $this->columns[0]["name"], $i);
			array_push($result, $nRecord);
		}
		////sistemare
	}
	
	public function LastData(){
		foreach ($this->columns as $i => $icolumn)
			if($icolumn["type"] == "DATETIME")
				break;
			
		if($this->hasTickData)
			$key2 = MULTIPLE_TIMESTAMP_ID_COLUMN_NAME;
		$lastRecord = $this->dbBroker->LastRecord($this->name, $icolumn["name"], $key2);
		return $this->Record2Data($lastRecord);
	}
	
	public function LastDataTimestamp(){
		foreach ($this->columns as $i => $icolumn)
			if($icolumn["type"] == "DATETIME")
				break;

		if($this->hasTickData)
			$key2 = MULTIPLE_TIMESTAMP_ID_COLUMN_NAME;
		$lastRecord = $this->dbBroker->LastRecord($this->name, $icolumn["name"], $key2);
		if(isset($lastRecord)){
			if(isset($key2))
				return array(strtotime($lastRecord[$icolumn["name"]]." ".TIMEZONE_CODE), $lastRecord[$key2]);
				
			return array(strtotime($lastRecord[$icolumn["name"]]." ".TIMEZONE_CODE));
		}
		return NULL;
	}
	
	//$rec :=	"ts"	=> "2014-08-28 15:00:00"
	//			"volume"=> "100"
	//			"close"	=> "52.43"
	//
	//$data :=	DT_ts	-> 2014-08-28 15:00:00
	//			F_volume-> 100
	//			F_close	-> 52.43
	private function Record2Data($rec){
		$data = new $this->dataTypeName();
		foreach ($this->columns as $iField => $field){
			$prefix = array_flip(TBL_StockData::$colTypes);
			
			$dataField = $prefix[$field["type"]]."_".$field["name"];
			$valueField = $rec[$field["name"]];
			$data->$dataField = $valueField;
		}
		
		return $data;
	}
	
	private function Data2Record($data){
		$values = array_values(get_object_vars($data));
		array_walk($values, 'TBL_StockData::addQuote');
		
		$columns = array_column($this->columns, "name");
		$record = array("columns" => $columns, "values" => $values);
		
		return $record;
	}
}

?>
